/*  AAG100-Steuergerät mit ARDUINO, LCD, Speicherbetrieb und BAND-Data von Andreas Nagel DL1AKP
 *   Copyright: nur zur privaten Nutzung durch Funkamateure oder SWL's, 
 *   jegliche andere, im speziellen kommerzielle Nutzung, bedarf der Genehmigung des Autors
 *   
  27.03.2016    V0.1  erste Bearbeitung
  21.07.2016    V0.8  Zusammenführung der beiden Versionen 10m / 6m in eine Version
  23.07.2016    V1.0  Finale Version, Feintuning, Erläuterungen ergänzt
  
 * TNX an Gerd, DL2VWR für die Stellung des AAG100-HF-Teils und die umfangreichen Tests  

Funktion:   
Steuergerät für AAG100 Antennentuner mit Band-Data Interface
Es soll das AAG100 per Drehencoder manuell abgestimmt werden (9C's, 12L's, HI/LO-Z, 1Reserve)
Nach einstellen des richtigen C-Wertes und L-Wertes und HI/LO soll dieser Zustand für das
entsprechende Band im EEPROM gespeichert werden. Die gespeicherten Werte sollen dann per Drehencoder
abrufbar sein, mit dem dazugehörigen Amateurfunk-Band (jeweils ein Wert für CW, ein Wert für SSB; 
respektive unterer und oberer Bandbereich)
Anzeige auf LCD korrekter C-Wert in pF, korrekter L-Wert in µH, HI/LO, Band, Speicherplatznummer
Beim Start soll ein vorher festgelegtes Band aus dem Speicher geladen werden (hard-coded 80m)
Aktivierung der Band-Data-Funktion mit Taster "HI/LO-Z" durch Klicken+Halten 2 Sekunden (Togglen)
Im Band-Data Betrieb mit Taster "HI/LO-Z" Umschalten des Bereiches CW/SSB im entsprechenden Band
mit "#define band_6m" kann eine Version z.B. für Elecraft K3 mit Band-Data 6m-Betrieb kompiliert werden,
oder eine Version ohne 6m-Band.

Aufteilung der Byte-Werte zum Speichern von L, C, HI/LO-Z, Band
L-Wert (long, 4Byte)        l_value
C-Wert (long, 4Byte)        c_value
HI/LO-Z (byte, 1Byte)       hilo
Band (Byte, 1Byte)          band

Abspeichern der Werte wie folgt:

Speicherstelle          Band                    mem_value
im EEPROM               Mode
--------------------------------------------------------
0                      160m cw                      0
20                     160m ssb                     1
40                      80m cw                      2
60                      80m ssb                     3
80                      40m cw                      4
100                     40m ssb                     5   
120                     30m                         6
140                     20m cw                      7
160                     20m ssb                     8
180                     17m cw                      9
200                     17m ssb                     10
220                     15m cw                      11
240                     15m ssb                     12
260                     12m cw                      13
280                     12m ssb                     14
300                     10m cw                      15
320                     10m ssb                     16
340                      6m cw                      17
360                      6m ssb                     18

**************************************************************************************************
*   ACHTUNG: Durch Einschreiben des entsprechenden Wertes von mem_value in Zeile 241             *
*   kann das Band und Mode, welches nach dem Einschalten aktiv sein soll, voreingestellt werden  *
**************************************************************************************************   
  
Größe: 15,9 kB (ohne Debugging)  kompiliert mit ARDUINO-IDE 1.8.5   
*/

char version[] = "V1.0 ";     // hier aktuelle Version Firmware

//#define band_6m             // wenn mit Band-Data auch 6m-Band geschaltet werden soll
                              // ohne 6m-Betrieb ==> Zeile auskommentieren
//#define debug               // wenn Parameter auf ser. Port ausgegeben werden sollen
                              // Achtung! Das braucht viel RAM! Bei Nichtbenutzung auskommentieren

// Libraries einbinden
#include <LiquidCrystal.h>          // LCD HD44780-Library, in IDE integriert
#include <Shifter.h>                // Library ShiftRegister 74HC595    http://code.bildr.org/download/944.zip
#include <ClickEncoder.h>           // Library Drehencoder:  https://github.com/soligen2010/encoder
#include <TimerOne.h>               // Library Timer:  http://playground.arduino.cc/Code/Timer1
#include <EEPROM.h>                 // Library EEPROM, in IDE integriert
#include <OneButton.h>              // Library Multifunktionsbutton:  https://github.com/mathertel/OneButton

// LCD-Display 4 I/O-Leitungen , 2 Control-Leitungen
#define lcd_rs 12         // LCD-Pin 4
#define lcd_enable 11     // LCD-Pin 6
#define lcd_d4 10         // LCD-Pin 11
#define lcd_d5 8          // LCD-Pin 12
#define lcd_d6 7          // LCD-Pin 13
#define lcd_d7 6          // LCD-Pin 14
#define LCD_CHARS   16    // 16 Zeichen
#define LCD_LINES    2    // 2 Zeilen
LiquidCrystal lcd(lcd_rs, lcd_enable, lcd_d4, lcd_d5, lcd_d6, lcd_d7);   // LCD initialisieren

// Shift-Register 74HC595
#define SER_Pin 4                                               // DS  SER_IN ( Pin14 am 595 )
#define RCLK_Pin 3                                              // ST  L_CLOCK  ( Pin12 am 595 )
#define SRCLK_Pin 2                                             // SH  CLOCK   ( Pin11 am 595 )
#define NUM_REGISTERS 3                                         // Anzahl der hintereinander geschalteten Register
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);   // Shift-Register initialisieren

// Encoder
#define ENCODER_PINA     A0                 // Anschlüsse des Encoders PinA
#define ENCODER_PINB     A1                 // Pin B    
#define ENCODER_BTN      A2                 // Taster des Encoders
#define ENCODER_STEPS_PER_NOTCH    4   
// Anzahl der Schritte, die der Encoder bei jeder Rastung
// macht. Bei meinem 4 Schritte. Der Mittel-Pin des Encoders auf GND, die beiden anderen Pins mit 10kOhm nach +5V
ClickEncoder encoder = ClickEncoder(ENCODER_PINA,ENCODER_PINB,ENCODER_BTN,ENCODER_STEPS_PER_NOTCH); // Encoder initialisieren

OneButton button1 (A4, true);   // Button initialisieren

// Beschaltung des ARDUINO
#define buzzer          A3                  // Anschluss Buzzer
#define band_a          A5                  // Band-Data Eingang A
#define band_b          A6                  // Band-Data Eingang B
#define band_c          A7                  // Band-Data Eingang C
#define band_d          5                   // Band-Data Eingang D
      
// Variablen
long last;                                  // Variable für Drehencoder 
long value;                                 // Variable für Drehencoder
long last_eep;                              // Variable für Drehencoder
long value_eep;                             // Variable für Drehencoder

boolean buzzer_flag = LOW;                  // Flag zur Erkennung, ob "Beep" gemacht werden muss
boolean Flag_banddata = LOW;                // Flag für Band-Data Betrieb
boolean last_Flag_banddata = LOW;           // Flag für Band-Data Betrieb
boolean Flag_taster_hilo = LOW;             // Flag für hi-lo-Z
boolean Flag_LC = LOW;                      // Flag, ob L (LOW) oder C (HIGH) eingestellt werden soll
boolean Flag_MEM = LOW;                     // Flag, ob Speicherbetrieb ja/nein 
boolean Flag_EEP = LOW;                     // Flag, ob in EEPROM geschrieben werden soll (LOW = nein)
boolean Flag_SSB = LOW;                     // Flag bei BandData-Betrieb, ob CW-Wert oder SSB-Wert geladen werden soll
boolean last_Flag_SSB = LOW;                // Flag-Wert zwischenspeichern

// 32 Bit Variablen zur Ansteuerung und Berechnung der Relaisausgbe
long c_value = 0;                           // Werte für Kondensatoren (0...511) 9Bit
long l_value = 0;                           // Werte für Spulen (0...4095) 12Bit
long c_value_old = 0;                       // Werte zwischenspeichern, um sie später wieder zu holen
long l_value_old = 0;                       // dito

// 32 Bit Variablen zum Zwischenspeichern für EEPROM
long c_eep = 0;                             // Wert für Kondensatoren
long l_eep = 0;                             // Wert für Spulen

// Ereignis X Dauer in msek bis zum Ausgeben der Daten auf die Relais im HF-Teil 
unsigned long X_vorhergehende_millis = 0;
unsigned long X_interval = 700;            // gewünschte Dauer (0,7 Sekunden)
boolean mem_change_Flag = LOW;

byte mem_value = 0;                         // Zählvariable Speicherbetrieb 
int mem_offset = 0;                         // Variable für Speicherplatz in EEPROM 
byte mem_hilo = 0;                          // Variable, um HI/LO-Z Wert in EEPROM abzuspeichern (LO=0; HI=100)
byte mem_hilo_old = 0;  
int bcd = 0;                                // Variable für Band-Data Betrieb
int last_bcd = 20;                          // Var. Zwischensp bcd-Wert (unplausibler Wert nötig, damit beim Start funktioniert.)
int bcd_confirm = 0;                        // Var. für BCD-Bestätigung

// Werte zur Berechnung der C-Werte des Gesamt-Kondensators in pF
const long c1 = 8;
const long c2 = 16;
const long c3 = 30;
const long c4 = 60;
const long c5 = 120;
const long c6 = 230;
const long c7 = 441;
const long c8 = 837;
const long c9 = 1590;

// Werte zur Berechnung der L-Werte der Gesamt-Spule in nH
const long l1 = 60000;
const long l2 = 35000;
const long l3 = 16500;
const long l4 = 7500;
const long l5 = 4000;
const long l6 = 2600;
const long l7 = 1500;
const long l8 = 800;
const long l9 = 450;
const long l10 = 260;
const long l11 = 160;
const long l12 = 80;

long c_gesamt = 0;              // Ergebnis Kondensator Berechnung zur Anzeige
long l_gesamt_nano = 0;         // Ergebnis Spule Berechnung in nH
float l_gesamt_micro = 0;       // Ergebnis Spule nach Umrechnung nH ==> µH
float temp_l = 0;               // zum Zwischenspeichern 



// ***********************************  setup() ******************************************
void setup() {
// 
// Pin-Funktion deklarieren (Eingang oder Ausgang)
pinMode (buzzer, OUTPUT);
pinMode (band_a, INPUT);
pinMode (band_b, INPUT);
pinMode (band_c, INPUT);
pinMode (band_d, INPUT);

// Taster-Funktionen einbinden
button1.attachClick(click1);                      // einfacher Druck
button1.attachDoubleClick(doubleclick1);          // Doppelklick
button1.attachLongPressStart(longPressStart1);    // lang drücken Beginn
button1.attachLongPressStop(longPressStop1);      // lang drücken Ende
button1.attachDuringLongPress(longPress1);        // lang drücken aktiv

// Dreh-Encoder richtig aktivieren
Timer1.initialize(1000);
Timer1.attachInterrupt(timerIsr);
last = -1;
last_eep = -1;
encoder.setButtonHeldEnabled(true);       // Klicken und halten mit Button (1,2sek.)
encoder.setDoubleClickEnabled(true);      // Doppelklicken mit Button
encoder.setButtonOnPinZeroEnabled(true);  // muss drin stehen
encoder.setAccelerationEnabled(true);     // schneller drehen, Wert schneller erhöhen  
//
Serial.begin(19200);                         // serieller Port mit 19200Bd aktivieren
lcd.begin(LCD_CHARS, LCD_LINES);            // LCD init mit 16 Zeichen und 2 Zeilen
lcd.clear();
lcd.print("AAG100-ATU "); lcd.print(version);   // Ausgabe auf LCD
lcd.setCursor(0,1);                         // Cursor in 2.Zeile
//
// mit 6m-Band oder ohne
#ifdef band_6m                              // Version 6m-Band
    lcd.print("DL1AKP 07/16/M06");
#endif

#ifndef band_6m                             // Version 10m-Band
    lcd.print("DL1AKP 07/16/M10");
#endif
//
digitalWrite(buzzer, HIGH);                 // Buzzer ein
delay(100);                                // 4 Sekunden zum lesen und 0,1 Sek. zum piepen
digitalWrite(buzzer, LOW);
delay(4000);        
lcd.clear();

// voreingestelltes Band laden
mem_value = 2;                              // Band nach dem Einschalten ** hier Wert einsetzen **  (jetzt 80m CW)
Flag_MEM = HIGH;                            // Flag Speicherbetrieb setzen
mem_change();                               // Unterprogramm ausführen
mem_change_Flag = HIGH;
} //--------------------------------- end setup --------------------------------------------





// **************** Hauptprogramm loop **********************************************************
void loop() {
  
  read_encoder();                   // Encoder abfragen

// Speicherbetrieb Relais schalten, wenn Zeit abgelaufen ist. Damit wird unnützes Schalten der Relais vermieden.
  if (mem_change_Flag == HIGH)
    {
        if (millis() - X_vorhergehende_millis >= X_interval)    // Zeit abgelaufen? ==> JA!
            {
                c_change();                                             // Wert für C's setzen
                l_change();                                             // Wert für L's setzen
                hilo_change();                                         // HI-Z oder LO-Z setzen
                mem_change_Flag = LOW;                // Flag rücksetzen, damit bereit für neues Erignis X
            }
    }

  
  button1.tick();                   // Abfrage Taster
  
  if (Flag_banddata == HIGH)
      {
          band_data();              // Unterprogramm Band-Data Betrieb
      }
  
  
}// -------------- end Hauptprogramm loop -------------------




// ************* Taster-Funktionen ****************************************

// Funktion wird aufgerufen, wenn der Taster einmal gedrueckt wurde
void click1() {
    #ifdef debug 
        Serial.println("Taster click."); 
    #endif

// Umschalten HI-Z / LO-Z Betrieb 
if (Flag_banddata == LOW && Flag_MEM == LOW){   // Taster hier bei LC-Betrieb aktiv!!
            
    if (Flag_taster_hilo == HIGH)               // wenn HI-Z...
            {
                Flag_taster_hilo = LOW;         // ...schalte in LO-Z
                mem_hilo = 0;                   // Wert für EEPROM
                lcd.setCursor(14,1);            // Cursor im LCD 2.Zeile, 15.Zeichen
                lcd.print("LO");                // auf LO-Z schalten
                shifter.setPin(21, LOW);
                shifter.setPin(22, HIGH);
                shifter.write();                // senden und anzeigen
            }
        else
            {
                Flag_taster_hilo = HIGH;        // ...ansonsten schalte in HI-Z
                mem_hilo = 100;                 // Wert für EEPROM
                lcd.setCursor(14,1);            // Cursor im LCD 2.Zeile, 15.Zeichen
                lcd.print("HI");                // auf HI-Z schalten
                shifter.setPin(21, HIGH);
                shifter.setPin(22, LOW);
                shifter.write();                //senden und anzeigen
            }
    }

// Umschalten CW/SSB Bereich bei BandData-Betrieb
if (Flag_banddata == HIGH)      
    {   
        // hier nach Wert mem_value entscheiden, was gemacht wird
        switch (mem_value){
            
            case 0:
                Flag_SSB = HIGH;    // 160m Band
                break;
            
            case 1:
                Flag_SSB = LOW;
                break;
            
            case 2:
                Flag_SSB = HIGH;    // 80m Band
                break;
            
            case 3:
                Flag_SSB = LOW;
                break;
            
            case 4:
                Flag_SSB = HIGH;    // 40m Band
                break;
            
            case 5:
                Flag_SSB = LOW;
                break;
            
            case 6:
                Flag_SSB = LOW;     // 30m Band, daher keine CW/SSB-Umschaltung
                break;
            
            case 7:
                Flag_SSB = HIGH;    // 20m Band
                break;
            
            case 8:
                Flag_SSB = LOW;
                break;
            
            case 9:
                Flag_SSB = HIGH;    // 17m Band
                break;
            
            case 10:
                Flag_SSB = LOW;
                break;  
            
            case 11:
                Flag_SSB = HIGH;    // 15m Band
                break;
            
            case 12:
                Flag_SSB = LOW;
                break;
            
            case 13:
                Flag_SSB = HIGH;    // 12m Band
                break;
            
            case 14:
                Flag_SSB = LOW;
                break;
            
            case 15:
                Flag_SSB = HIGH;    // 10m Band
                break;
            
            case 16:
                Flag_SSB = LOW;
                break;
         
         #ifdef band_6m             // nur kompilieren bei 6m-Version    
            case 17:
                Flag_SSB = HIGH;   
                break;
            
            case 18:
                Flag_SSB = LOW;
                break;
         #endif                     // Ende 6m-Version
        } // ende switch
    }
} // click1 ende



// Funktion wird ausgefuehrt, wenn der Taster 2x kurz hintereinander gedrückt wurde (Doppelklick)
void doubleclick1() {
#ifdef debug     
    Serial.println("Taster doubleclick.");
#endif
} // doubleclick1 end



// Funktion wird ausgeführt, wenn der Taster lang gedrückt wird
void longPressStart1() {
    #ifdef debug 
        Serial.println("Taster longPress start");
    #endif
    buzzer_flag = HIGH;         // Flag setzen
    if(buzzer_flag == HIGH)
        {
            digitalWrite(buzzer, HIGH);   // Pieper für eine Sekunde an
            delay(1000);
            digitalWrite(buzzer, LOW);
        }
} // longPressStart1 end



// Funktion wird immer wieder ausgeführt, während der Taster lang gedrückt wird
// hier nicht benötigt, also ohne Funktion
void longPress1() {
    #ifdef debug 
        Serial.println("Taster longPress...");
    #endif
} // longPress1



// Funktion wird einmal ausgeführt, nachdem Taster losgelassen wurde nach langem Drücken
void longPressStop1() {
    #ifdef debug 
        Serial.println("Taster longPress stop");
    #endif
    buzzer_flag = LOW;
    last_Flag_banddata = Flag_banddata;
    Flag_banddata = !Flag_banddata;             // Flag togglen
} // longPressStop1

// ---------------------- Ende Tasterfunktionen -----------------------------------------------




// ************************** EEPROM-Funktionen ********************************************

// Methode long in eeprom schreiben
void eepromWriteLong(long lo, int adr) {
    // long Wert in das EEPROM schreiben
    // Eingabe : adr Speicherplatz
    // Eingabe : lo Zahl, Wertebereich -2.147.483.648 bis 2.147.483.647
    //
    // Matthias Busse 23.5.2014 Version 1.0

    byte by;

    for(int i=0;i< 4;i++) {
        by = (lo >> ((3-i)*8)) & 0x000000ff;
        EEPROM.write(adr+i, by);
    }
} // eepromWriteLong ende


// Methode long aus eeprom lesen
long eepromReadLong(int adr) {
    // long int Wert aus 4 Byte EEPROM lesen
    // Eingabe : adr bis adr+3
    // Ausgabe : long Wert
    //
    // Matthias Busse 23.5.2014 Version 1.0

    long lo=0;

    for(int i=0;i< 3;i++){
        lo += EEPROM.read(adr+i);
        lo = lo << 8;
    }
    lo += EEPROM.read(adr+3);
    return lo;
} // eepromReadLong ende

// ----------------------------- Ende EEPROM-Funktionen --------------------------------------





// *************************** Unterprogramm Band Data Betrieb ************************
void band_data(){
    #ifdef debug 
        Serial.println("Band-Data-Betrieb");
    #endif
    lcd.setCursor(8,0);
    lcd.print("auto ");
    
// lokale Variablen
byte mem_old = mem_value;       // Wert zwischenspeichern
long l_old = l_value;
long c_old = c_value;
long value_old = value;
boolean Flag_error = LOW;       // Flag für unplausible Band-Data-Werte
boolean Flag_taster_hilo_old = Flag_taster_hilo;

// ---- solange Band-Data-Betrieb ---
while (Flag_banddata == HIGH){
    button1.tick();             // Abfrage Taster

// hier Wert zweimal hintereinander auslesen und vergleichen. Nur wenn er gleich ist, weiter im Programm
// War nötig, weil manchmal aufgrund der Abtastgeschwindigkeit der Bits Fehlschaltungen vorkamen
confirm:    
// entsprechendes Bit setzen
    if(digitalRead(band_a) == HIGH) bitSet(bcd, 0);             // A5
    if(digitalRead(band_a) == LOW)  bitClear(bcd, 0);
    if(analogRead(band_b) > 512)    bitSet(bcd, 1);             // A6 geht nur analog!!
    if(analogRead(band_b) <= 512)   bitClear(bcd, 1);
    if(analogRead(band_c) > 512)    bitSet(bcd, 2);             // A7 geht nur analog!
    if(analogRead(band_c) <= 512)   bitClear(bcd, 2);
    if(digitalRead(band_d) == HIGH) bitSet(bcd, 3);             // 5
    if(digitalRead(band_d) == LOW)  bitClear(bcd, 3);
delay(10);
// entsprechendes Bit setzen
    if(digitalRead(band_a) == HIGH) bitSet(bcd_confirm, 0);     // A5
    if(digitalRead(band_a) == LOW)  bitClear(bcd_confirm, 0);
    if(analogRead(band_b) > 512)    bitSet(bcd_confirm, 1);     // A6 geht nur analog!!
    if(analogRead(band_b) <= 512)   bitClear(bcd_confirm, 1);
    if(analogRead(band_c) > 512)    bitSet(bcd_confirm, 2);     // A7 geht nur analog!
    if(analogRead(band_c) <= 512)   bitClear(bcd_confirm, 2);
    if(digitalRead(band_d) == HIGH) bitSet(bcd_confirm, 3);     // 5
    if(digitalRead(band_d) == LOW)  bitClear(bcd_confirm, 3);
if (bcd != bcd_confirm) goto confirm;

if (bcd != last_bcd || last_Flag_SSB != Flag_SSB || last_Flag_banddata != Flag_banddata) // wenn Taster gedrückt oder TRX hat QRG geändert
    {
        Flag_error = LOW;   // Flag Band-Data-Fehler zurück setzen
        
        switch (bcd){

            case 1:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("160m-Band CW");
                        mem_value = 0;
                        mem_change(); c_change(); l_change(); hilo_change(); // Unterprogramme ausführen
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("160m-Band SSB");
                        mem_value = 1;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;
            
            case 2:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("80m-Band CW");
                        mem_value = 2;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("80m-Band SSB");
                        mem_value = 3;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;
            
            case 3:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("40m-Band CW");
                        mem_value = 4;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("80m-Band SSB");
                        mem_value = 5;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;

            case 4:
                Serial.println("30m-Band");
                mem_value = 6;
                mem_change(); c_change(); l_change(); hilo_change();
            break;

            case 5:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("20m-Band CW");
                        mem_value = 7;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("20m-Band SSB");
                        mem_value = 8;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;

            case 6:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("17m-Band CW");
                        mem_value = 9;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("17m-Band SSB");
                        mem_value = 10;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;

            case 7:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("15m-Band CW");
                        mem_value = 11;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("15m-Band SSB");
                        mem_value = 12;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
        break;

            case 8:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("12m-Band CW");
                        mem_value = 13;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("12m-Band SSB");
                        mem_value = 14;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;

            case 9:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("10m-Band CW");
                        mem_value = 15;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("10m-Band SSB");
                        mem_value = 16;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;
         
         #ifdef band_6m
            case 0:
                if (Flag_SSB == LOW)
                    {
                        Serial.println("6m-Band CW");
                        mem_value = 17;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
                if (Flag_SSB == HIGH)
                    {
                        Serial.println("6m-Band SSB");
                        mem_value = 18;
                        mem_change(); c_change(); l_change(); hilo_change();
                    }
            break;
         #endif
         
            default:
                Flag_error = HIGH;
            break;
            
        }// end switch
        
    } // end if

if (Flag_error == HIGH)
    {
        Serial.println("Band-Data undefiniert!"); // wenn kein korrektes Afu-Band anliegt
        lcd.setCursor(8,1);                     // dann aktuellen Wert beibehalten und
        lcd.print("err ");                     
        digitalWrite(buzzer, HIGH);              // Buzzer piepen lassen
        delay(100);
        digitalWrite(buzzer, LOW);
        delay(500);
    }

last_bcd = bcd;             // akt. Zustände als letzten Zustand speichern, für nächsten Durchlauf
last_Flag_SSB = Flag_SSB;   
last_Flag_banddata = Flag_banddata;
} // ende while

if (Flag_MEM == HIGH)   // Speicherbetrieb
    {
        mem_value = mem_old;            // Wert wieder holen
        value = mem_old;
        c_value = c_old;
        l_value = l_old;
        mem_change();
        
        #ifdef debug 
            Serial.println("mem_change");
            Serial.print("mem_value= ");
            Serial.println(mem_value);
        #endif
    }
else  // LC-Betrieb
    {
        lcd.setCursor(8,0);
        lcd.print("L/C  ");
        lcd.setCursor(8,1);
        lcd.print("     ");
        c_value = c_old;
        l_value = l_old;
        value = value_old;
        //
        if (Flag_taster_hilo_old == LOW)        // vorhergeh. Zustand HI/LO-Z wieder herstellen
            {
                mem_hilo = 0;                   // Wert für EEPROM
                lcd.setCursor(14,1);            // Cursor im LCD 2.Zeile, 15.Zeichen
                lcd.print("LO");                // auf LO-Z schalten
                shifter.setPin(21, LOW);
                shifter.setPin(22, HIGH);
                shifter.write();                //senden und anzeigen
            }
        else
            {
                mem_hilo = 100;                 // Wert für EEPROM
                lcd.setCursor(14,1);            // Cursor im LCD 2.Zeile, 15.Zeichen
                lcd.print("HI");                // auf HI-Z schalten
                shifter.setPin(21, HIGH);
                shifter.setPin(22, LOW);
                shifter.write();                //senden und anzeigen
            }
        c_change();
        l_change();
    }

}// -------------------------- Ende Band Data Betrieb ----------------------------------




// *************************** Unterprogramm Encoder abfragen ************************
void read_encoder() {

    // Encoder auslesen
    value += encoder.getValue();     // bedeutet:  value = value + encoder.getValue()                   
    
    if (value != last) {                                // wenn neuer Wert, d.h. Encoder wurde gedreht
        last = value;                                   // neuen Wert als alten Wert speichern
        
        if (Flag_LC == HIGH && Flag_MEM == LOW)         // wenn Modus "C-Wert einstellen" aktiv
            {
                value = min(value,511);                 // Wertebereich begrenzen max. 511 (9Bit)
                value = max(value,0);                   // Wertebereich begrenzen min. 0
                c_value = value;                        // Wert aus Drehencoder übernehmen
                #ifdef debug 
                    Serial.print("c-value ");
                    Serial.println(c_value);
                    Serial.println();
                #endif
                c_change();                             // Unterprogramm anspringen
            } 
        else if (Flag_LC == LOW && Flag_MEM == LOW)     // wenn Modus "L-Wert einstellen" aktiv
            {
                value = min(value,4095);                // Wertebereich begrenzen max. 4096 (12Bit)
                value = max(value,0);                   // Wertebereich begrenzen min. 0
                l_value = value;
                #ifdef debug 
                    Serial.print("l-value ");
                    Serial.println(l_value);
                    Serial.println();
                #endif
                l_change();                             // Unterprogramm anspringen
            }
        else if (Flag_MEM == HIGH)                      // Speicherbetrieb
            {
                X_vorhergehende_millis = millis();      // Zwischenspeichern für Berechnung abgelaufener Zeit
                mem_change_Flag = HIGH;                 // Flag setzen, dass Ereignis eingetreten ist
                
             // 6m-Betrieb ja/nein?
             #ifndef band_6m                            // nur bis 10m 
                value = min(value,16);                  // Wertebereich begrenzen max. 10m-Band
             #endif
             #ifdef band_6m                             // bis 6m
                value = min(value,18);                  // Wertebereich begrenzen 6m-Band
             #endif
             
                value = max(value,0);                   // Wertebereich begrenzen 
                mem_value = value;
                #ifdef debug 
                    Serial.print("mem_value ");
                    Serial.println(mem_value);
                    Serial.println();
                #endif
                mem_change();                           // Unterprogramm anspringen
            }
    }

// Button des Encoder auslesen
    // Variable b entspricht dem Status des Button wie folgt:
    // 5=Klick, 6=Doppelklick, 3=Halten, 4=Losgelassen
    ClickEncoder::Button b = encoder.getButton();
    if (b != ClickEncoder::Open) {
        
        switch (b) {  // was wurde mit dem Button gemacht?
            
            // -------------------------------------------------------------------------------------
            case ClickEncoder::Clicked:                 // einfacher Klick; Toggle L-Wert / C-Wert ändern
            #ifdef debug 
                Serial.print("Clicked, Umschalten L-Wert / C-Wert ändern:");
            #endif
                Flag_LC = !Flag_LC;                     // Wert togglen
                if (Flag_LC == HIGH && Flag_MEM == LOW)
                    {
                        lcd.setCursor(15,0);
                        lcd.print("C");
                        value = c_value;                // vorhergehenden Wert der Einstellung wieder holen
                    }
                else if (Flag_LC == LOW && Flag_MEM == LOW)
                    {
                        lcd.setCursor(15,0);
                        lcd.print("L");
                        value = l_value;                // vorhergehenden Wert der Einstellung wieder holen
                    }
            break;
            
            // -----------------------------------------------------------------------------------------
            case ClickEncoder::DoubleClicked:           // Doppelklick; Toggle Speicherbetrieb, LC-Betrieb
            #ifdef debug 
                Serial.println("DoubleClicked, Umschalten Speicherbetrieb, LC-Betrieb");
            #endif
            Flag_MEM = !Flag_MEM;                       // Flag "Speicherbetrieb" togglen
            
            if (Flag_MEM == LOW)                        // in LC-Mode schalten
                {
                    if (Flag_LC == LOW)
                        {
                            lcd.setCursor(15,0);
                            lcd.print("L");
                        } 
                    else
                        {
                            lcd.setCursor(15,0);
                            lcd.print("C");
                        }
                    
                    l_value = l_value_old;              // Werte zurück holen
                    c_value = c_value_old;
                    mem_hilo = mem_hilo_old;
                    
                    #ifdef debug 
                        Serial.println("C/L-Einstell-Modus");
                        Serial.print("l_value_old= ");
                        Serial.println(l_value_old);
                        Serial.print("c_value_old= ");
                        Serial.println(c_value_old);
                        Serial.print("mem_hilo_old= ");
                        Serial.println(mem_hilo_old);
                        Serial.print("mem_hilo= ");
                        Serial.println(mem_hilo);
                    #endif
                    
                    // HI-LO-Z ??
                    if (mem_hilo == 100) Flag_taster_hilo = HIGH;     // Flag, damit Taster richtig abgefragt wird
                    if (mem_hilo == 0)  Flag_taster_hilo = LOW;      
                    hilo_change;                                      // Unterprogramm anspringen
                    
                    // Berechnung C-Wert in pF
                    if (bitRead(c_value, 0) == true) c_gesamt = c_gesamt + c1;
                    if (bitRead(c_value, 1) == true) c_gesamt = c_gesamt + c2;
                    if (bitRead(c_value, 2) == true) c_gesamt = c_gesamt + c3;
                    if (bitRead(c_value, 3) == true) c_gesamt = c_gesamt + c4;
                    if (bitRead(c_value, 4) == true) c_gesamt = c_gesamt + c5;
                    if (bitRead(c_value, 5) == true) c_gesamt = c_gesamt + c6;
                    if (bitRead(c_value, 6) == true) c_gesamt = c_gesamt + c7;
                    if (bitRead(c_value, 7) == true) c_gesamt = c_gesamt + c8;
                    if (bitRead(c_value, 8) == true) c_gesamt = c_gesamt + c9;
                    
                    // Anzeige LCD mit Formatierung
                    if (c_gesamt < 10)
                        {
                            lcd.setCursor(0,0);
                            lcd.print(c_gesamt);
                            lcd.print("pF   ");
                        }
                    else if (c_gesamt >= 10 && c_gesamt < 100)
                        {
                            lcd.setCursor(0,0);
                            lcd.print(c_gesamt);
                            lcd.print("pF  ");
                        }
                    else if (c_gesamt >= 100 && c_gesamt < 1000)
                        {
                            lcd.setCursor(0,0);
                            lcd.print(c_gesamt);
                            lcd.print("pF ");
                        }
                    else
                        {
                            lcd.setCursor(0,0);
                            lcd.print(c_gesamt);
                            lcd.print("pF");
                        }
                    
                    c_gesamt = 0;   // Variable zurück setzen für neue Berechnung
                    
                    for (int i=0; i<=8; i++){
                        shifter.setPin(i, !(bitRead(c_value, i))); 
                        }
                        // das "!" bedeutet negiert, weil die Relais in Reihe mit den C's sind.
                        // deshalb muss der jeweilige C aktivert werden, indem das Relais abfällt, d.h. diesen zuschaltet.
                    
                    shifter.write(); // senden und anzeigen
                    
                    // Berechnung L-Wert erst in nH, dann in µH
                    if (bitRead(l_value, 11) == true) l_gesamt_nano = l_gesamt_nano + l1;
                    if (bitRead(l_value, 10) == true) l_gesamt_nano = l_gesamt_nano + l2;
                    if (bitRead(l_value, 9) == true) l_gesamt_nano = l_gesamt_nano + l3;
                    if (bitRead(l_value, 8) == true) l_gesamt_nano = l_gesamt_nano + l4;
                    if (bitRead(l_value, 7) == true) l_gesamt_nano = l_gesamt_nano + l5;
                    if (bitRead(l_value, 6) == true) l_gesamt_nano = l_gesamt_nano + l6;
                    if (bitRead(l_value, 5) == true) l_gesamt_nano = l_gesamt_nano + l7;
                    if (bitRead(l_value, 4) == true) l_gesamt_nano = l_gesamt_nano + l8;
                    if (bitRead(l_value, 3) == true) l_gesamt_nano = l_gesamt_nano + l9;
                    if (bitRead(l_value, 2) == true) l_gesamt_nano = l_gesamt_nano + l10;
                    if (bitRead(l_value, 1) == true) l_gesamt_nano = l_gesamt_nano + l11;
                    if (bitRead(l_value, 0) == true) l_gesamt_nano = l_gesamt_nano + l12;
                    temp_l = l_gesamt_nano;     // Variable an Float-Variable übergeben
                    l_gesamt_micro = temp_l / 1000; // Umrechnung in µH mit Float-Variable
                    
                    // Anzeige LCD mit Formatierung
                    if (l_gesamt_micro < 10)
                        {
                            lcd.setCursor(0,1);
                            lcd.print(l_gesamt_micro, 1);       // anzeigen mit 1 Kommastelle
                            lcd.print("uH  ");
                        }
                    else if (l_gesamt_micro >= 10 && l_gesamt_micro < 100)
                        {
                            lcd.setCursor(0,1);
                            lcd.print(l_gesamt_micro, 1);       // anzeigen mit 1 Kommastelle
                            lcd.print("uH ");
                        }
                    else
                        {
                            lcd.setCursor(0,1);
                            lcd.print(l_gesamt_micro, 1);       // anzeigen mit 1 Kommastelle
                            lcd.print("uH");
                        }
                    
                    l_gesamt_nano = 0;                          // zurücksetzen für neue Berechnung
                    l_gesamt_micro = 0;                         // dito
                    
                    // die Bits 9 bis 20 (L's des AAG100) in Shiftregister schreiben
                    for (int i=9; i<=20; i++){
                        shifter.setPin(i, bitRead(l_value, (i-9)));
                    }
                    shifter.write();                            //senden und anzeigen
                        
                    lcd.setCursor(8,0);
                    lcd.print("L/C  ");
                    lcd.setCursor(8,1);                         // zweite Zeile Anzeige des Bandes löschen
                    lcd.print("    ");
                    if (Flag_LC == LOW)                         // den richtigen wert wieder herstellen
                        {
                            value = l_value;                    // Wert für L
                        }
                    else
                        {
                            value = c_value;                    // Wert für C
                        }
                
                }
            else // in Speicherbetrieb schalten
                {
                    l_value_old = l_value;                      // Werte sichern
                    c_value_old = c_value;
                    mem_hilo_old = mem_hilo;
                    mem_change();                               // Unterprogramm Speicherbetrieb
                    
                    #ifdef debug
                        Serial.println("Speicherbetrieb");
                        Serial.print("l_value_old= ");
                        Serial.println(l_value_old);
                        Serial.print("c_value_old= ");
                        Serial.println(c_value_old);
                        Serial.print("mem_hilo_old= ");
                        Serial.println(mem_hilo_old);
                    #endif
                }
            break;
            
            // -------------------------------------------------------------------------------------
            case ClickEncoder::Held:            // Klicken + Halten
            #ifdef debug
                Serial.println("Klicken+Halten Encoderbutton.");
            #endif
            buzzer_flag = HIGH;
            if(buzzer_flag == HIGH)
                {
                    digitalWrite(buzzer, HIGH);
                    delay(1000);
                    digitalWrite(buzzer, LOW);
                }
            break;
            
            // ---------------------------------------------------------------------------------------
            case ClickEncoder::Released:        // Losgelassen; Wert in EEPROM speichern
            buzzer_flag = LOW;
            #ifdef debug
                Serial.println("Click+Halten+Losgelassen, Werte in EEPROM schreiben");
            #endif
            Flag_EEP = HIGH;                    // Flag setzen
            eep_encoder();                      // Unterprogramm anspringen         
            break;
        } // end switch
    } // end if
}// --------------------------- Ende Unterprogramm -----------------------------------




// ************************ Unterprogramm C-Wert-Änderung *************************
void c_change(){

c_eep = c_value;    // Wert übernehmen in EEPROM-Variable   

// Berechnung C-Wert in pF
    if (bitRead(c_value, 0) == true) c_gesamt = c_gesamt + c1;
    if (bitRead(c_value, 1) == true) c_gesamt = c_gesamt + c2;
    if (bitRead(c_value, 2) == true) c_gesamt = c_gesamt + c3;
    if (bitRead(c_value, 3) == true) c_gesamt = c_gesamt + c4;
    if (bitRead(c_value, 4) == true) c_gesamt = c_gesamt + c5;
    if (bitRead(c_value, 5) == true) c_gesamt = c_gesamt + c6;
    if (bitRead(c_value, 6) == true) c_gesamt = c_gesamt + c7;
    if (bitRead(c_value, 7) == true) c_gesamt = c_gesamt + c8;
    if (bitRead(c_value, 8) == true) c_gesamt = c_gesamt + c9;
    
    #ifdef debug      
        Serial.print("Gesamt-C= ");
        Serial.print(c_gesamt);
        Serial.println(" pF");
        Serial.println();
    #endif
    
// Anzeige LCD mit Formatierung
    if (c_gesamt < 10)
        {
            lcd.setCursor(0,0);
            lcd.print(c_gesamt);
            lcd.print("pF   ");
        } 
    else if (c_gesamt >= 10 && c_gesamt < 100)
        {
            lcd.setCursor(0,0);
            lcd.print(c_gesamt);
            lcd.print("pF  ");
        }
    else if (c_gesamt >= 100 && c_gesamt < 1000)
        {
            lcd.setCursor(0,0);
            lcd.print(c_gesamt);
            lcd.print("pF ");
        }
    else
        {
            lcd.setCursor(0,0);
            lcd.print(c_gesamt);
            lcd.print("pF");
        }
    
    c_gesamt = 0;   // Variable zurück setzen für neue Berechnung
    
// die Bits 0 bis 8 (C's des AAG100) in Shiftregister schreiben
   for (int i=0; i<=8; i++){
        shifter.setPin(i, !(bitRead(c_value, i))); // das "!" bedeutet negiert, weil die Relais in Reihe mit den C's sind.
        // deshalb muss der jeweilige C aktivert werden, indem das Relais abfällt, d.h. diesen zuschaltet.
    }
    shifter.write(); // senden und anzeigen
    
}// --------------------------- Ende Unterprogramm -----------------------------------




// *********************** Unterprogramm L-Wert-Änderung *****************************
void l_change(){

l_eep = l_value;    // Wert in EEPROM-Variable übernehmen

// Berechnung L-Wert erst in nH, dann in µH
    if (bitRead(l_value, 11) == true) l_gesamt_nano = l_gesamt_nano + l1;
    if (bitRead(l_value, 10) == true) l_gesamt_nano = l_gesamt_nano + l2;
    if (bitRead(l_value, 9) == true) l_gesamt_nano = l_gesamt_nano + l3;
    if (bitRead(l_value, 8) == true) l_gesamt_nano = l_gesamt_nano + l4;
    if (bitRead(l_value, 7) == true) l_gesamt_nano = l_gesamt_nano + l5;
    if (bitRead(l_value, 6) == true) l_gesamt_nano = l_gesamt_nano + l6;
    if (bitRead(l_value, 5) == true) l_gesamt_nano = l_gesamt_nano + l7;
    if (bitRead(l_value, 4) == true) l_gesamt_nano = l_gesamt_nano + l8;
    if (bitRead(l_value, 3) == true) l_gesamt_nano = l_gesamt_nano + l9;
    if (bitRead(l_value, 2) == true) l_gesamt_nano = l_gesamt_nano + l10;
    if (bitRead(l_value, 1) == true) l_gesamt_nano = l_gesamt_nano + l11;
    if (bitRead(l_value, 0) == true) l_gesamt_nano = l_gesamt_nano + l12;
    temp_l = l_gesamt_nano;     // Variable an Float-Variable übergeben
    l_gesamt_micro = temp_l / 1000; // Umrechnung in µH mit Float-Variable

    #ifdef debug
        Serial.print("Gesamt-L= ");
        Serial.print(l_gesamt_micro);
        Serial.println(" uH");
        Serial.println();
    #endif
    
// Anzeige LCD mit Formatierung
    if (l_gesamt_micro < 10)
        {
            lcd.setCursor(0,1);
            lcd.print(l_gesamt_micro, 2);       // anzeigen mit 2 Kommastelle
            lcd.print("uH  ");
        } 
    else if (l_gesamt_micro >= 10 && l_gesamt_micro < 100)
        {
            lcd.setCursor(0,1);
            lcd.print(l_gesamt_micro, 2);       // anzeigen mit 2 Kommastelle
            lcd.print("uH ");
        }
    else
        {
            lcd.setCursor(0,1);
            lcd.print(l_gesamt_micro, 2);       // anzeigen mit 2 Kommastelle
            lcd.print("uH");
        }
    
    l_gesamt_nano = 0;  // zurücksetzen für neue Berechnung
    l_gesamt_micro = 0;  // dito
    
// die Bits 9 bis 20 (L's des AAG100) in Shiftregister schreiben
    for (int i=9; i<=20; i++){
        shifter.setPin(i, bitRead(l_value, (i-9)));
    }
    shifter.write(); //senden und anzeigen
    
}// --------------------------- Ende Unterprogramm -----------------------------------





// *********************** Unterprogramm High-Z oder Low-Z Änderung *****************************
void hilo_change()
{
  if (mem_hilo == 0)  // wenn LO-Z
            {
                lcd.setCursor(14,1);                    // Cursor im LCD 2.Zeile, 15.Zeichen
                lcd.print("LO");                        // auf LO-Z schalten
                shifter.setPin(21, LOW);
                shifter.setPin(22, HIGH);
                shifter.write();                        // senden
            }

  if (mem_hilo == 100)    // wenn HI-Z
            {
                lcd.setCursor(14,1);                    // Cursor im LCD 2.Zeile, 15.Zeichen
                lcd.print("HI");                        // auf HI-Z schalten    
                shifter.setPin(21, HIGH);
                shifter.setPin(22, LOW);
                shifter.write();                        // senden 
            }
}// --------------------------- Ende Unterprogramm -----------------------------------





// ********************** Unterprogramm Speicherplatz Änderung ************************
void mem_change(){
    
    #ifdef debug  // Ausgabe auf seriellem Port im Debugging Mode
        Serial.println("Speicherbetrieb");
        Serial.print("mem_value= ");
        Serial.println(mem_value);
        Serial.print("Flag_banddata= ");
        Serial.println(Flag_banddata);
    #endif
    
    // BandData-Betrieb JA/NEIN?
    if (Flag_banddata == LOW)       // nein
        {
            lcd.setCursor(8,0);     // Ausgabe LCD
            lcd.print("MEM");
            lcd.setCursor(11,0);
            if (mem_value < 10)
                {
                    lcd.print(" ");
                    lcd.print(mem_value);
                }
            else
                {
                    lcd.print(mem_value);
                }
        }
    else                            // ja
        {
            lcd.setCursor(8,0);
            lcd.print("auto");
        }
    
// Anzeige des Bandes bei Speicherbetrieb
    switch (mem_value)
    {
    case 0:
        lcd.setCursor(8,1);   // auf entsprechende Stelle des Display springen
        lcd.print("160c");
        mem_offset = 0;
        break;
    case 1:
        lcd.setCursor(8,1);
        lcd.print("160s");
        mem_offset = 20;
        break;
    case 2:
        lcd.setCursor(8,1);
        lcd.print(" 80c");
        mem_offset = 40;
        break;
    case 3:
        lcd.setCursor(8,1);
        lcd.print(" 80s");
        mem_offset = 60;
        break;
    case 4:
        lcd.setCursor(8,1);
        lcd.print(" 40c");
        mem_offset = 80;
        break;
    case 5:
        lcd.setCursor(8,1);
        lcd.print(" 40s");
        mem_offset = 100;
        break;
    case 6:
        lcd.setCursor(8,1);
        lcd.print(" 30 ");
        mem_offset = 120;
        break;
    case 7:
        lcd.setCursor(8,1);
        lcd.print(" 20c");
        mem_offset = 140;
        break;
    case 8:
        lcd.setCursor(8,1);
        lcd.print(" 20s");
        mem_offset = 160;
        break;
    case 9:
        lcd.setCursor(8,1);
        lcd.print(" 17c");
        mem_offset = 180;
        break;
    case 10:
        lcd.setCursor(8,1);
        lcd.print(" 17s");
        mem_offset = 200;
        break;
    case 11:
        lcd.setCursor(8,1);
        lcd.print(" 15c");
        mem_offset = 220;
        break;
    case 12:
        lcd.setCursor(8,1);
        lcd.print(" 15s");
        mem_offset = 240;
        break;
    case 13:
        lcd.setCursor(8,1);
        lcd.print(" 12c");
        mem_offset = 260;
        break;
    case 14:
        lcd.setCursor(8,1);
        lcd.print(" 12s");
        mem_offset = 280;
        break;
    case 15:
        lcd.setCursor(8,1);
        lcd.print(" 10c");
        mem_offset = 300;
        break;
    case 16:
        lcd.setCursor(8,1);
        lcd.print(" 10s");
        mem_offset = 320;
        break;
    #ifdef band_6m                  // mit 6m-Band
    case 17:
        lcd.setCursor(8,1);
        lcd.print(" 06c");
        mem_offset = 340;
        break;
    case 18:
        lcd.setCursor(8,1);
        lcd.print(" 06s");
        mem_offset = 360;
        break;  
    #endif  
    } // ende switch

if (Flag_EEP == LOW)        // Werte aus EEPROM holen
    {
        /*
        zu lesende Werte:
        L-Wert (long, 4 Byte)  l_value
        C-Wert (long, 4Byte)   c_value
        HI/LO-Z (byte)         mem_hilo
        */
        l_value = eepromReadLong(mem_offset);
        mem_offset = mem_offset + 4;        // Weiterspringen an richtige Adresse
        c_value = eepromReadLong(mem_offset);
        mem_offset = mem_offset + 4;            // Weiterspringen an richtige Adresse
        mem_hilo = EEPROM.read(mem_offset);
        
        #ifdef debug
            Serial.println("Flag_EEP = LOW  Werte aus EEPROM holen.");
            Serial.print("c_value= ");
            Serial.println(c_value);
            Serial.print("l_value= ");
            Serial.println(l_value);
            Serial.print("mem_offset= ");
            Serial.println(mem_offset);
            Serial.print("mem_hilo= ");
            Serial.println(mem_hilo);   
            Serial.println("EEPROM-Read OK.");
        #endif
        
    } // end if

value = mem_value;      // vorhergehenden Wert wieder holen
}// --------------------------- Ende Unterprogramm -----------------------------------





// ***************** Unterprogramm Werte in EEPROM ablegen *****************************
void eep_write(){
/*
zu speichernde Werte:
L-Wert (long, 4 Byte)  l_eep
C-Wert (long, 4Byte)   c_eep
HI/LO-Z (byte)         mem_hilo
*/
eepromWriteLong(l_eep, mem_offset);
mem_offset = mem_offset + 4;                            // Weiterspringen an richtige Adresse
eepromWriteLong(c_eep, mem_offset);
mem_offset = mem_offset + 4;                            // Weiterspringen an richtige Adresse   
EEPROM.write(mem_offset, mem_hilo);                     // Byte HI/LO-Z

#ifdef debug
    Serial.print("mem_offset (band) = ");
    Serial.println(mem_offset);
    Serial.print("l_eep= ");
    Serial.println(l_eep);
    Serial.print("c_eep= ");
    Serial.println(c_eep);
    Serial.print("mem_hilo= ");
    Serial.println(mem_hilo);
    Serial.println("EEPROM-Write OK."); 
#endif
}// --------------------------- Ende Unterprogramm -----------------------------------




// ******************* Unterprogramm Encoder auslesen für EEPROM ****************************
void eep_encoder(){ 

#ifdef debug
    Serial.println("EEP_encoder");
    Serial.print("Flag_EEP= ");
    Serial.println(Flag_EEP);
#endif

while (Flag_EEP == HIGH)                                // solang noch nicht gespeichert wurde
{
    

    value_eep += encoder.getValue();                    // Encoder auslesen

    if (value_eep != last_eep) {                        // wenn neuer Wert, d.h. Encoder wurde gedreht
        last_eep = value_eep;                           // neuen Wert als alten Wert speichern
        
     #ifndef band_6m             
        value_eep = min(value_eep,16);                  // Wertebereich begrenzen max. 10m
     #endif
     
     #ifdef band_6m             
        value_eep = min(value_eep,18);                  // Wertebereich begrenzen bis 6m
     #endif
        
        value_eep = max(value_eep,0);                   // Wertebereich begrenzen
    }
    
    #ifdef debug
        Serial.println("EEPROM-Betrieb");
    #endif
    lcd.setCursor(8,0);
    lcd.print("EEP");
    lcd.setCursor(11,0);
    if (value_eep < 10)
        {
            lcd.print(" ");
            lcd.print(value_eep);
        }
    else
        {
            lcd.print(value_eep);
        }

    // Anzeige des Bandes
    switch (value_eep)
    {
        case 0:
            lcd.setCursor(8,1);
            lcd.print("160c");
            mem_offset = 0;
        break;
        case 1:
            lcd.setCursor(8,1);
            lcd.print("160s");
            mem_offset = 20;
        break;
        case 2:
            lcd.setCursor(8,1);
            lcd.print(" 80c");
            mem_offset = 40;
        break;
        case 3:
            lcd.setCursor(8,1);
            lcd.print(" 80s");
            mem_offset = 60;
        break;
        case 4:
            lcd.setCursor(8,1);
            lcd.print(" 40c");
            mem_offset = 80;
        break;
        case 5:
            lcd.setCursor(8,1);
            lcd.print(" 40s");
            mem_offset = 100;
        break;
        case 6:
            lcd.setCursor(8,1);
            lcd.print(" 30 ");
            mem_offset = 120;
        break;
        case 7:
            lcd.setCursor(8,1);
            lcd.print(" 20c");
            mem_offset = 140;
        break;
        case 8:
            lcd.setCursor(8,1);
            lcd.print(" 20s");
            mem_offset = 160;
        break;
        case 9:
            lcd.setCursor(8,1);
            lcd.print(" 17c");
            mem_offset = 180;
        break;
        case 10:
            lcd.setCursor(8,1);
            lcd.print(" 17s");
            mem_offset = 200;
        break;
        case 11:
            lcd.setCursor(8,1);
            lcd.print(" 15c");
            mem_offset = 220;
        break;
        case 12:
            lcd.setCursor(8,1);
            lcd.print(" 15s");
            mem_offset = 240;
        break;
        case 13:
            lcd.setCursor(8,1);
            lcd.print(" 12c");
            mem_offset = 260;
        break;
        case 14:
            lcd.setCursor(8,1);
            lcd.print(" 12s");
            mem_offset = 280;
        break;
        case 15:
            lcd.setCursor(8,1);
            lcd.print(" 10c");
            mem_offset = 300;
        break;
        case 16:
            lcd.setCursor(8,1);
            lcd.print(" 10s");
            mem_offset = 320;
        break;
     
     #ifdef band_6m  
        case 17:
            lcd.setCursor(8,1);
            lcd.print(" 06c");
            mem_offset = 340;
        break;
        case 18:
            lcd.setCursor(8,1);
            lcd.print(" 06s");
            mem_offset = 360;
        break;
     #endif
    }

//------------- Button des Encoder auslesen --------------
ClickEncoder::Button b = encoder.getButton();
if (b != ClickEncoder::Open) {
    
    switch (b) {  // was wurde mit dem Button gemacht?
        
        // -------------------------------------------------------------------------------------
        case ClickEncoder::Clicked:     // einfacher Klick, Abbruch
            #ifdef debug    
                Serial.println("Click, Speicherbetrieb verl. OHNE speichern");
            #endif
            lcd.setCursor(8,0);
            lcd.print("     ");
            lcd.setCursor(8,1);
            lcd.print("     ");
            Flag_EEP = LOW;     // Flag zurück setzen
        break;
        
        // -----------------------------------------------------------------------------------------
        case ClickEncoder::DoubleClicked:   // Doppelklick, keine Funktion
            #ifdef debug    
                Serial.println("DoubleClicked");
            #endif
        break;
        
        // -------------------------------------------------------------------------------------
        case ClickEncoder::Held:            // Klicken + Halten
            buzzer_flag = HIGH;
            if(buzzer_flag == HIGH)
                {
                    digitalWrite(buzzer, HIGH);
                    delay(1000);
                    digitalWrite(buzzer, LOW);
                }
        break;
        
        // ---------------------------------------------------------------------------------------
        case ClickEncoder::Released:        // Losgelassen; Werte in EEPROM schreiben
            buzzer_flag = LOW;
            #ifdef debug
                Serial.println("Click+Halten, Werte in EEPROM schreiben");
            #endif
            eep_write();                    // Unterprogramm anspringen
            lcd.setCursor(8,0);
            lcd.print("WRITE");
            lcd.setCursor(8,1);
            lcd.print("  OK ");
            delay(2000);
            lcd.setCursor(8,0);
            lcd.print("     ");
            lcd.setCursor(8,1);
            lcd.print("     ");
            Flag_EEP = LOW;                 // Flag reset
        break;
        } // ende switch
    } // ende if
delay(250);
} // ende while

}// --------------------------- Ende Unterprogramm -----------------------------------




// *************** Interrupt-Routine ****************
void timerIsr() {
    encoder.service();
}// -------------- Ende Interrupt-Routine ---------------


// ******************************************  ENDE *********************************************************
// Andreas Nagel  DL1AKP / AB7VT im Jahre 2016/2018



